/**
 * 伪异步IO Server端的思路：
 * 1 服务端启动一个 ServerSocket 监听指定端口号
 * 2 轮询是否有客户端连接，此时阻塞在客户端连接前
 * 3 指定线程池大小和内部阻塞队列大小构造一个有界Socket任务线程池 TimeServerHandlerExecutePool，将新的Socket连接封装成 Runnable任务
 * 4 当有客户端连接时，使用 TimeServerHandlerExecutePool 执行Socket任务
 *
 *
 * 优点： 不再为每个Socket连接请求创建一个独立线程，改用线程池持有的线程去处理，这样做避免了大量请求时线程资源耗尽的问题。
 * 弊端： ①根据IO中输入流的特点，
 * 当网络环境不好或传输数据量大时，比如需要60s才能处理完，读取流的通信线程会阻塞在消息队列中，其他接入消息也只能在队列中排队；
 * 由于线程池是阻塞队列，所以当队列积满后，后续入队列的操作将被阻塞；
 * 由于只有一个Acceptor接收，新的客户端建连请求将被拒绝，后续的客户端将会大量超时；
 * 由于几乎所有连接都超时，调用者会认为系统崩溃，无法接受新的请求消息。
 * @author chentl
 * @version V1.0
 * @Project leisurely
 * @Title TimeServer.java
 * @Description 伪异步I/O server端
 * @Package com.echo.ioex.wio.server
 * @date 2020/9/18 12:44 下午
 * @Copyright: 陈泰来の学习档案 .
 */
package com.echo.ioex.wio.server;

import com.echo.ioex.bio.server.handler.TimeServerHandler;
import com.echo.ioex.wio.server.pool.TimeServerHandlerExecutePool;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


@Slf4j
public class TimeServer {

    public static void main(String[] args) throws IOException {
        int port = 9999;
        if (args != null && args.length > 0) {
            try {

            } catch (NumberFormatException e) {
                //默认端口
            }
        }

        ServerSocket server = null;
        try {
            server = new ServerSocket(port);
            log.info("[server]Time server work on port :{}", port);
            Socket socket = null;
            //创建 I/O 任务线程池
            TimeServerHandlerExecutePool singleExecutor = new TimeServerHandlerExecutePool(50, 100);
            while (true) {
                //将Socket封装成一个task --> 任务线程池运行新的客户端连接处理
                singleExecutor.execute(new TimeServerHandler(server.accept()));
            }
        } finally {
            if (server != null) {
                log.info("[server]服务已关闭");
                server.close();
                server = null;
            }
        }
    }

}
